In [2]:
exec(open("L_modules.py").read())
exec(open("L_vars_paths.py").read())
/opt/conda/lib/python3.9/importlib/__init__.py:169: UserWarning: The NumPy module was reloaded (imported a second time). This can in some cases result in small but subtle issues and is discouraged.
  _bootstrap._exec(spec, module)
In [3]:
with open(pf_ohlcv, "rb") as f2r: # don't forget to change into ohlcvL above
    ohlcv = cPickle.load(f2r) #   
ohlcvO = jh.ohlcv_ohlcL_usdV(ohlcv, logPrices = False, usdVolume = True) #                        # O for 'original' - adjust volume to USD, leave prices unlogged              
ohlcv  = jh.ohlcv_ohlcL_usdV(copy.deepcopy(ohlcvO), logPrices = True, usdVolume = False) #        # logged prices, leave volume, already put in USD, unchanged
with open(pf_talib_def, "rb") as f2r:  
    talib_def = cPickle.load(f2r)
with open(pf_talib_pers, "rb") as f2r:  
    talib_pers = cPickle.load(f2r)
with open(pf_nf_4h, "rb") as f2r:  
    fin_4h = cPickle.load(f2r)
with open(pf_nf_1d, "rb") as f2r:  
    fin_1d = cPickle.load(f2r)    

FF = pd.concat([fin_4h, fin_1d, talib_pers, talib_def.shift()], axis = 1) #
FF = FF.loc[:, ~FF.columns.duplicated() ]
del talib_pers, fin_4h, fin_1d 
In [4]:
dvsO = ['ytfB', 'ytf', 'v', 'y', 'Dy', 'h_l', 'Dc', 'c_wmin', 'xh_l__wR', 'h_l__wR', 'h_wmin', 'l_wmin', 'o', 'c', 'h', 'l'] + ['h_l_1d', 'Dy_1d', 'ytf_1d', 'y_1d', 
                  'v_1d', 'Dc_1d', 'c_wmin_1d', 'xh_l__wR_1d', 'h_l__wR_1d', 'h_wmin_1d', 'l_wmin_1d', 'o_1d', 'c_1d', 'h_1d', 'l_1d']
def nyf(nb = 4, y = "FF[(tok, 'ytf')]", o = "FF[(tok, 'o')]", h = "FF[(tok, 'h')]", l = "FF[(tok, 'l')]", c = "FF[(tok, 'c')]", co = 0):
    """
    coming up w/ standard for feat. engineering funcs
    """
    o_l, h_o, h_l = o-l, h-o, h-l
    up = y > co
    dn = y <=co
    o4 = o.shift(-nb)
    h4 = h.shift(-nb)
    hs = jh.lagMat(h4, nb, inct=True)
    l4 = l.shift(-nb)
    ls = jh.lagMat(l4, nb, inct=True)
    hs = hs.max(axis=1)
    ls = ls.min(axis=1)
    
    #print(abs(o4-o).describe())
    
    fin = (o4-o)/(hs - ls)
    #fin = y / hl
    
    messedUp = fin[ fin.isnull() ] 
    if len(messedUp) > 1:
        #print( len(messedUp), 'replaced while creating feature' ) 
        fin[ fin.isnull() ] = 0
        
    return(fin)

for tok in ['btc', 'eth', 'sol', 'link']:
    #print(tok)
    var_sn = 'ytfB'
    var_sn2= 'ytfB2'
    FF[(tok, var_sn)] = FF[(tok, 'ytf')] / abs(FF[(tok, 'h_l')])    
    FF[(tok, var_sn2)]= nyf(y = FF[(tok, 'ytf')], o = FF[(tok, 'o')], h = FF[(tok, 'h')], l = FF[(tok, 'l')], c = FF[(tok, 'c')], co = 0)
    b_lm = jh.lagMat(FF[(tok, var_sn)], 8)
    # b_lm2= jh.lagMat(FF[(tok, var_sn2)],8)
    for i in range(0, 8):
        FF[(tok, var_sn+'_L' +str(i+1))] = b_lm.iloc[:, i]
        #FF[(tok, var_sn2+'_L'+str(i+1))] = b_lm2.iloc[:, i]
dvs = dvsO+ [var_sn] + [var_sn2]
In [5]:
with open(pf_DyMBS, "rb") as f:  
     fin = cPickle.load(f) 
with open(pf_voM, "rb") as f:  
    h_lD = cPickle.load(f) 
    
In [6]:
from IPython.display import Markdown as md
from backtesting import Backtest
from backtesting import Strategy
import warnings
warnings.simplefilter(action='ignore')
/opt/conda/lib/python3.9/site-packages/backtesting/_plotting.py:50: UserWarning: Jupyter Notebook detected. Setting Bokeh output to notebook. This may not work in Jupyter clients without JavaScript support (e.g. PyCharm, Spyder IDE). Reset with `backtesting.set_bokeh_output(notebook=False)`.
  warnings.warn('Jupyter Notebook detected. '
Loading BokehJS ...

In [7]:
tok = 'btc'
Q = jh.X_XsForMods(X= FF, bp=[14000, (FF.shape[0]-962)], co=500, dvCol = (tok, 'ytfB2'), dropCols =  dvs)

fc = jh.fcSer(Q['III_iv']['btc'], fin[tok]['mf'])
ind = fc.index
dv = fin[tok]['dv'] 
Tok = ar(aL)[ [tok.upper() in i for i in aL] ][0]
[Parallel(n_jobs=3)]: Using backend ThreadingBackend with 3 concurrent workers.
[Parallel(n_jobs=3)]: Done  44 tasks      | elapsed:    0.0s
[Parallel(n_jobs=3)]: Done 194 tasks      | elapsed:    0.1s
[Parallel(n_jobs=3)]: Done 444 tasks      | elapsed:    0.2s
[Parallel(n_jobs=3)]: Done 677 out of 677 | elapsed:    0.3s finished
In [8]:
Q = jh.X_XsForMods(X= FF, bp=[14000, (FF.shape[0]-962)], co=500, dvCol = (tok, 'h_l'), dropCols =  dvs)
In [9]:
h_l_fc = jh.fcSer(Q['III_iv']['btc'], h_lD[tok])
h_l_dv = Q['III_dv']
In [10]:
ohlc = ohlcvO.loc[ind, Tok]
fohlc= pd.concat([ohlc['StartDate'], 
                  fc.shift(), 
                  h_l_fc.shift(), # because trades get filled wrt closing/next open
                  ohlc[['Open', 'High', 'Low', 'Close']]], axis=1)
fohlc.rename(columns={fohlc.columns[1]:'fc', fohlc.columns[2]:'h_l_fc'}, inplace=True)
In [ ]:
 
In [11]:
jh.repScatter(fv = h_l_fc, ob=h_l_dv, title = tok.upper() + 'Volatility Forecast v. Observed Volatility').show(renderer='notebook') 
jh.repScatter(fv=fc, ob=dv, title=tok.upper() + ' forecast & observed values', withOnsides=False).show(renderer='notebook')
jh.ons_x_thresh(fc, dv, title = "Onsidedness by Portion of Positions Put Live").show(renderer='notebook')
px.line(fc, title='Forecast'  ).update_traces(line_color='#03213a').show(renderer='notebook')
px.line(ohlc.Close, title='Price'  ).update_traces(line_color='#03213a').show(renderer='notebook')
In [15]:
the_fc = lambda x : x
    
class fc_thresh(Strategy):
    co = .7
    vco= .85
    qc = abs(fc).quantile(co)
    qcn=-qc
    vqc= abs(h_l_fc).quantile(vco)
    def init(self):    
        self.fc = self.I(the_fc, self.data.fc)
        self.vfc= self.I(the_fc, self.data.h_l_fc)
    def next(self):
        cur_time = self.data.index[-1]
        if self.fc >= self.qc:
            for trade in self.trades:
                if trade.is_short:
                    trade.close()
            if self.vfc > self.vqc:
                self.buy()
        elif self.fc <= self.qcn:
            for trade in self.trades:
                if trade.is_long:
                    trade.close()
            if self.vfc > self.vqc:
                self.sell()
        for trade in self.trades:
            if (cur_time - trade.entry_time) >= pd.Timedelta('1 hour'):
                trade.close()
                
                
bt = Backtest(data = fohlc, strategy = fc_thresh, cash = 10000000, trade_on_close = True, exclusive_orders = False)        
stats = bt.run()
print(stats)
bt.plot()
Start                     2022-10-28 03:15:00
End                       2022-11-07 03:15:00
Duration                     10 days 00:00:00
Exposure Time [%]                   11.134235
Equity Final [$]                   10535583.8
Equity Peak [$]                    10573912.4
Return [%]                           5.355838
Buy & Hold Return [%]                3.258487
Return (Ann.) [%]                  353.380882
Volatility (Ann.) [%]              113.251811
Sharpe Ratio                         3.120311
Sortino Ratio                      194.054539
Calmar Ratio                       304.854782
Max. Drawdown [%]                   -1.159178
Avg. Drawdown [%]                   -0.297851
Max. Drawdown Duration        6 days 23:45:00
Avg. Drawdown Duration        0 days 17:24:00
# Trades                                   24
Win Rate [%]                        70.833333
Best Trade [%]                       1.328371
Worst Trade [%]                     -0.363037
Avg. Trade [%]                       0.217798
Max. Trade Duration           0 days 01:00:00
Avg. Trade Duration           0 days 00:57:00
Profit Factor                        6.705045
Expectancy [%]                       0.218552
SQN                                  2.683276
_strategy                           fc_thresh
_equity_curve                             ...
_trades                       Size  EntryB...
dtype: object
Out[15]:
Row(
id = '2322', …)
align = 'start',
aspect_ratio = None,
background = None,
children = [GridBox(id='2319', ...), ToolbarBox(id='2321', ...)],
cols = 'auto',
css_classes = [],
disabled = False,
height = None,
height_policy = 'auto',
js_event_callbacks = {},
js_property_callbacks = {},
margin = (0, 0, 0, 0),
max_height = None,
max_width = None,
min_height = None,
min_width = None,
name = None,
sizing_mode = 'stretch_width',
spacing = 0,
subscribed_events = [],
syncable = True,
tags = [],
visible = True,
width = None,
width_policy = 'auto')
In [13]:
px.histogram(stats['_trades']['PnL'], nbins=16, color_discrete_sequence=['#03213a'] ).show(renderer='notebook') 
In [ ]:
 
In [ ]: